home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Expert
/
Windows Expert.iso
/
utility
/
sysgraf4.zip
/
SOURCE.ZIP
/
SYSGRAPH.C
next >
Wrap
C/C++ Source or Header
|
1991-08-15
|
39KB
|
1,569 lines
/*
* System Graph - Version 4.00 (June 6, 1991.)
* By James Straub
*
* For a history of this program please refer to the documentaion.
*
*
*
* Programmer notes:
*
* This program is written for Borland C++.
*
* "#pragma argsused" tells the compiler not to be
* alarmed if I don't use a variable that was created.
*
* Please feel free to modify this program.
*
*
*
* NOTE: It's now August and I have finally decided to send this out...
* Now with more experience in Windows programing under my belt
* I realize that this baby could use some improvementa. Some day
* I hope to get around to it. Have fun with it...
*
*/
/************************************************************************
* Files to include.
*/
#include <windows.h>
#include "sysgraph.h"
/************************************************************************
* Global data structure.
*/
typedef struct {
HANDLE hInstance; // The instance of this program
HWND hWnd; // ID of the program's window
char name[NAME_SIZE]; // name of program
BOOL halt; // Halts graph when in a dialog box
} Program_Data;
typedef struct {
POINT table[MAX_POINTS_ALL]; // Holds graph points
int msg_count; // # of messages since timer
int apex; // Highest point on graph
} Graph_Data;
typedef struct {
short int graph_type; // Type of graph.
short int update_time; // Time to update graph
BOOL on_top; // Keep graph on top
BOOL on_caption; // Keep graph on active caption
BOOL auto_rescale; // Automatically rescale graph
BOOL iconic; // Window is iconic
RECT window_position; // Graph's position on desktop
} Program_State;
/************************************************************************
* Global declarations.
*/
Program_Data prog;
Graph_Data graph;
Program_State state;
BOOL popup_mode = TRUE;
/************************************************************************
* This initializes the first instance of the program by setting up the
* window class and registering it.
*
* INPUT: hInstance = This is the instance of this program.
*
* OUTPUT: NONE
*/
BOOL InitFirst(HANDLE hInstance)
{
WNDCLASS WndClass;
/*
* Define the window class.
*/
WndClass.style = CS_VREDRAW | CS_HREDRAW;
WndClass.lpfnWndProc = MainProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = (HICON) NULL;
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH) NULL;
WndClass.lpszMenuName = (LPSTR) NULL;
WndClass.lpszClassName = (LPSTR) prog.name;
/*
* Register the window class.
*/
if ( RegisterClass(&WndClass) == 0)
return(FALSE);
return(TRUE);
} /* InitFirst */
/************************************************************************
* This initializes all the global vars in this program. This includes
* clearing the graph table.
*
* INPUT: hInstance = This is the instance of this program.
* hWnd = This is a handle to the window just created.
*
* OUTPUT: NONE
*/
void InitGlobals(HANDLE hInstance, HWND hWnd)
{
int count;
/*
* Initialize the global
* variables.
*/
prog.hWnd = hWnd;
prog.hInstance = hInstance;
prog.halt = FALSE;
graph.msg_count = 0;
graph.apex = 0;
/*
* Initialize the graph table.
*/
for (count = 0; count < MAX_POINTS; count++)
{
graph.table[count].x = count;
graph.table[count].y = 0;
}
graph.table[MAX_POINTS].x = LAST_POINT;
graph.table[MAX_POINTS+1].x = 0;
} /* InitGlobals */
/************************************************************************
* This is where we initialize each and every instance of this program.
*
* INPUT: hInstance = This is the instance of this program.
* hPrevInstance = This is the instance of the previous program.
*
* OUTPUT: NONE
*/
#pragma argsused
BOOL WinInit(HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int cmdShow)
{
HWND hWnd;
/*
* Load the program name from the string
* table. If it could not find the string
* load a default string name.
*/
if (LoadString(hInstance, IDS_NAME, (LPSTR)prog.name, NAME_SIZE) == 0)
strcpy(prog.name,"No name found!");
/*
* Set the WINCLASS of the window only
* if this is the first instance of the
* program.
*/
if (! hPrevInstance)
{
if (InitFirst(hInstance) == FALSE)
return(FALSE);
}
/*
* Create the window for the program.
*/
hWnd = CreateWindow((LPSTR) prog.name,
(LPSTR) prog.name,
WS_POPUP,
DEF_WIN_LEFT,
DEF_WIN_TOP,
(DEF_WIN_RIGHT - DEF_WIN_LEFT),
(DEF_WIN_BOTTOM - DEF_WIN_TOP),
(HWND) NULL,
(HMENU) NULL,
hInstance,
(LPSTR) NULL);
/*
* Make sure the window was
* created.
*/
if (! hWnd)
return(FALSE);
/*
* Initialize all global vars.
*/
InitGlobals(hInstance, hWnd);
/*
* Update the window but don't
* show it yet.
*/
ShowWindow(hWnd, SW_HIDE);
UpdateWindow(hWnd);
return(TRUE);
} /* WinInit */
/************************************************************************
* This function gets the setup information from the win.ini file. If
* the user never saved his/her setup then use the defaults.
*
* INPUT: NONE.
*
* OUTPUT: NONE
*/
void GetProgramSetup()
{
SetCursor(LoadCursor(NULL, IDC_WAIT));
state.graph_type = GetProfileInt((LPSTR) INI_NAME,
(LPSTR) GRAPH_TYPE_KEY,
DEF_GRAPH_TYPE);
state.auto_rescale = GetProfileInt((LPSTR) INI_NAME,
(LPSTR) AUTO_RESCALE_KEY,
DEF_AUTO_RESCALE);
state.update_time = GetProfileInt((LPSTR) INI_NAME,
(LPSTR) UPDATE_TIME_KEY,
DEF_UPDATE_TIME);
state.on_top = GetProfileInt((LPSTR) INI_NAME,
(LPSTR) ON_TOP_KEY,
DEF_ON_TOP);
state.on_caption = GetProfileInt((LPSTR) INI_NAME,
(LPSTR) ON_CAPTION_KEY,
DEF_ON_CAPTION);
state.iconic = GetProfileInt((LPSTR) INI_NAME,
(LPSTR) ICONIC_KEY,
DEF_ICONIC);
state.window_position.left = GetProfileInt((LPSTR) INI_NAME,
(LPSTR) WIN_LEFT_KEY,
DEF_WIN_LEFT);
state.window_position.right = GetProfileInt((LPSTR) INI_NAME,
(LPSTR) WIN_RIGHT_KEY,
DEF_WIN_RIGHT);
state.window_position.top = GetProfileInt((LPSTR) INI_NAME,
(LPSTR) WIN_TOP_KEY,
DEF_WIN_TOP);
state.window_position.bottom = GetProfileInt((LPSTR) INI_NAME,
(LPSTR) WIN_BOTTOM_KEY,
DEF_WIN_BOTTOM);
SetCursor(LoadCursor(NULL, IDC_ARROW));
} /* GetProgramSetup */
/************************************************************************
* This function saves the setup to the win.ini file.
*
* INPUT: NONE.
*
* OUTPUT: NONE
*/
void SetProgramSetup()
{
char dummy[10]; // Temporary storage for number
/*
* Show the wait cursor.
*/
SetCursor(LoadCursor(NULL, IDC_WAIT));
sprintf(dummy, "%1.2f", VERSION_NUMBER);
WriteProfileString((LPSTR) INI_NAME,
(LPSTR) VERSION_KEY,
(LPSTR) dummy);
sprintf(dummy, "%d", state.graph_type);
WriteProfileString((LPSTR) INI_NAME,
(LPSTR) GRAPH_TYPE_KEY,
(LPSTR) dummy);
sprintf(dummy, "%d", state.auto_rescale);
WriteProfileString((LPSTR) INI_NAME,
(LPSTR) AUTO_RESCALE_KEY,
(LPSTR) dummy);
sprintf(dummy, "%d", state.update_time);
WriteProfileString((LPSTR) INI_NAME,
(LPSTR) UPDATE_TIME_KEY,
(LPSTR) dummy);
sprintf(dummy, "%d", state.on_top);
WriteProfileString((LPSTR) INI_NAME,
(LPSTR) ON_TOP_KEY,
(LPSTR) dummy);
sprintf(dummy, "%d", state.on_caption);
WriteProfileString((LPSTR) INI_NAME,
(LPSTR) ON_CAPTION_KEY,
(LPSTR) dummy);
sprintf(dummy, "%d", state.iconic);
WriteProfileString((LPSTR) INI_NAME,
(LPSTR) ICONIC_KEY,
(LPSTR) dummy);
sprintf(dummy, "%d", state.window_position.left);
WriteProfileString((LPSTR) INI_NAME,
(LPSTR) WIN_LEFT_KEY,
(LPSTR) dummy);
sprintf(dummy, "%d", state.window_position.right);
WriteProfileString((LPSTR) INI_NAME,
(LPSTR) WIN_RIGHT_KEY,
(LPSTR) dummy);
sprintf(dummy, "%d", state.window_position.top);
WriteProfileString((LPSTR) INI_NAME,
(LPSTR) WIN_TOP_KEY,
(LPSTR) dummy);
sprintf(dummy, "%d", state.window_position.bottom);
WriteProfileString((LPSTR) INI_NAME,
(LPSTR) WIN_BOTTOM_KEY,
(LPSTR) dummy);
/*
* Show the arrow cursor.
*/
SetCursor(LoadCursor(NULL, IDC_ARROW));
} /* SetProgramSetup */
/************************************************************************
* After reading the win.ini file we must put our settings to work.
* This includes setting the timer and showing the window.
*
* INPUT: NONE.
*
* OUTPUT: NONE
*/
BOOL DoSetup()
{
/*
* Set the timer to its default
* value and were done!
*/
if (! SetProgramTimer(state.update_time - 9))
return(FALSE);
/*
* Position the window where the
* user wants it.
*/
SetWindowPos(prog.hWnd, 1,
state.window_position.left,
state.window_position.top,
(state.window_position.right -
state.window_position.left),
(state.window_position.bottom -
state.window_position.top),
SWP_NOZORDER);
/*
* Show the window the
* way the user wants it.
*/
if (state.iconic)
ShowWindow(prog.hWnd, SW_SHOWMINIMIZED);
else
ShowWindow(prog.hWnd, SW_SHOWNORMAL);
return(TRUE);
} /* DoSetup */
/************************************************************************
* This function is the main entry point for this Windows application.
*
* INPUT: hInstance = This is the instance of this program.
* hPrevInstance = This is the instance of the previous program.
*
* OUTPUT: TRUE of FALSE depending if initialization went well.
*
*/
#pragma argsused
int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
MSG Msg; // holds windows message structure.
/*
* Initialize the Window and all
* the program data!
*/
if (! WinInit(hInstance, hPrevInstance, lpszCmdLine, nCmdShow))
return(FALSE);
/*
* Get the settings from the
* win.ini file if they are there.
*/
GetProgramSetup();
/*
* This sets up the program the
* way the user wants it.
*/
if (! DoSetup())
return(FALSE);
/*
* Main loop for the program. While
* looping I count the number of times
* this loop was iterated.
*/
while ( THE_SKY_IS_BLUE ) {
graph.msg_count++;
if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
{
if (Msg.message == WM_QUIT)
break;
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
return(TRUE);
} /* WinMain */
/************************************************************************
* This tells Windows to send a timer message at a certain time from now.
*
* INPUT: time_in_sec = The time in seconds that the timer will be set to.
*
* RETURNS: TRUE or FALSE depending if it worked or not
*
*/
BOOL SetProgramTimer( int time_in_sec )
{
/*
* Kill the old timer and
* start a new one.
*/
KillTimer(prog.hWnd, 1);
if (SetTimer(prog.hWnd, 1, time_in_sec*1000, NULL) == 0)
return(FALSE);
return(TRUE);
} /* SetProgramTimer */
/************************************************************************
* This function is passed a value of which it puts on the graph table.
* While doing this I find the peek of all the points. Since this
* graph is a representation of polygon, we must update the last two
* points of the table in order to "close" the polygon.
*
* INPUT: new_point = The new point to append to the graph.
*
* OUTPUT: NONE
*
*/
void AddPoint( int new_point )
{
register int index; // Used to increment graph
/*
* If in auto rescale mode then
* clear the peek.
*/
if (state.auto_rescale)
graph.apex = 0;
/*
* Move all points down one and update
* the peek value.
*/
for (index = 0; index < LAST_POINT; index++) {
graph.table[index].y = graph.table[index+1].y;
graph.apex = max(graph.apex, graph.table[index].y);
}
graph.table[LAST_POINT].y = new_point;
/*
* If the new point is larger
* than the peek make it the peek!
*/
graph.apex = max(graph.apex, new_point);
/*
* This creates the last vertices
* to "close" the polygon of points.
*/
graph.table[LAST_POINT+1].y = graph.apex;
graph.table[LAST_POINT+2].y = graph.apex;
} /* AddPoint */
/************************************************************************
* This function rescales the graph by updating the peek value.
*
* INPUT: NONE
*
* OUTPUT: NONE
*
*/
void RescaleGraph()
{
int index;
graph.apex = 0;
for (index = 0; index < MAX_POINTS; index++)
graph.apex = max(graph.apex, graph.table[index].y);
} /* RescaleGraph */
/************************************************************************
* This changes the window from a popup to its normal state and back.
* This is used to be able to move and size the window.
*
* INPUT: NONE
*
* OUTPUT: NONE
*
*/
void ChangeWinStyle()
{
RECT window_rect; // Our window's size and position
static BOOL on_cap_status; // Holds the on_caption status
popup_mode = ! popup_mode;
/*
* If popup_mode is true then make
* the window a popup window.
*/
if (popup_mode)
{
SetWindowLong(prog.hWnd, GWL_STYLE, WS_POPUP);
state.on_caption = on_cap_status;
}
else
{
SetWindowLong(prog.hWnd, GWL_STYLE, STANDARD_STYLE);
on_cap_status = state.on_caption;
state.on_caption = FALSE;
}
/*
* This is a way of making windows
* aware of the change done to the
* window.
*/
GetWindowRect(prog.hWnd, &window_rect);
MoveWindow(prog.hWnd, window_rect.left, window_rect.top,
window_rect.right - window_rect.left,
window_rect.bottom - window_rect.top,
TRUE);
ShowWindow(prog.hWnd, SW_SHOW);
} /* ChangeWinStyle */
/************************************************************************
* This function moves our window on the caption bar of the currently
* active parent window.
*
* INPUT: NONE
*
* OUTPUT: NONE
*
*/
void MoveToTopWindowCap()
{
static RECT oldrect; // The rect of the last positioning
HWND hWndAct; // The active windows handle
HWND hWndPAct; // The parent window of the active one
RECT rect; // The current active window's rect
LONG act_win_style; // The active windows style
/*
* If we are minimized
* then do nothing.
*/
if (IsIconic(prog.hWnd))
return;
/*
* Get the active window handle
* and make sure its the parent.
*/
hWndAct = GetActiveWindow();
if ((hWndPAct = GetParent(hWndAct)) != NULL)
hWndAct = hWndPAct;
/*
* If the host window has not changed
* size or position then do nothing.
*/
GetWindowRect(hWndAct, &rect);
if (EqualRect(&rect,&oldrect))
{
/*
* Only show the window if it's
* blocked.
*/
if (GetWindow(prog.hWnd,GW_HWNDFIRST) != prog.hWnd)
ShowWindow(prog.hWnd, SW_SHOWNA);
return;
}
else
oldrect = rect;
/*
* Show the graph in it's normal poisition
* if there is no window to place it on or if
* the active window is hidden or if the
* active window is iconic.
*/
if ( (hWndAct == prog.hWnd) ||
(! IsWindowVisible(hWndAct)) ||
(IsIconic(hWndAct)) )
{
SetWindowPos(prog.hWnd, NULL,
state.window_position.left,
state.window_position.top,
(state.window_position.right -
state.window_position.left),
(state.window_position.bottom -
state.window_position.top),
SWP_NOACTIVATE);
return;
}
/*
* To position the graph on a window
* we must find the position in which
* to place it. We do this by looking
* at the window style.
*/
act_win_style = GetWindowLong(hWndAct, GWL_STYLE);
if (! (act_win_style & WS_CAPTION))
return;
/*
* This following three "if"
* statements check to see
* what type of window the host is,
* in order to properly position
* the window.
*/
if (act_win_style & WS_THICKFRAME)
{
SetWindowPos(prog.hWnd, NULL,
rect.left +
GetSystemMetrics(SM_CXDLGFRAME) +
GetSystemMetrics(SM_CXBORDER) +
GetSystemMetrics(SM_CXSIZE),
rect.top + GetSystemMetrics(SM_CYDLGFRAME),
(3 * GetSystemMetrics(SM_CXSIZE)),
GetSystemMetrics(SM_CYSIZE),
SWP_NOACTIVATE);
return;
}
if (act_win_style & DS_MODALFRAME)
{
SetWindowPos(prog.hWnd, NULL,
rect.left + +
GetSystemMetrics(SM_CXSIZE) +
(2 * GetSystemMetrics(SM_CXBORDER)) + 5,
rect.top + GetSystemMetrics(SM_CYBORDER) + 4,
(3 * GetSystemMetrics(SM_CXSIZE)),
GetSystemMetrics(SM_CYSIZE),
SWP_NOACTIVATE);
return;
}
if (act_win_style & WS_BORDER)
{
SetWindowPos(prog.hWnd, NULL,
rect.left +
GetSystemMetrics(SM_CXSIZE) +
(2 * GetSystemMetrics(SM_CXBORDER)),
rect.top + GetSystemMetrics(SM_CYBORDER),
(3 * GetSystemMetrics(SM_CXSIZE)),
GetSystemMetrics(SM_CYSIZE),
SWP_NOACTIVATE);
return;
}
} /* MoveToTopWindowCap */
/************************************************************************
* This function gets run everytime this window receives a timer
* message.
*
* INPUT: NONE
*
* OUTPUT: NONE
*
*/
void DoTimmer(WORD wParam)
{
/*
* If this is the timer for the
* menu then display it.
*/
if (wParam == 2)
{
KillTimer(prog.hWnd, 2);
DialogBox(prog.hInstance, (LPSTR) "MENU_BOX",
prog.hWnd, MakeProcInstance(
(FARPROC) MenuDialog, prog.hInstance));
return;
}
/*
* If the system is halted then
* pause graph display. It is
* halted when a dialog box is
* showing.
*/
if (! prog.halt)
{
/*
* Add a point to the graph table.
*/
AddPoint(graph.msg_count / (state.update_time - 9 ));
/*
* Move the window on the caption
* of the host window if the user
* wants it that way. Otherwise
* if the user wants the graph on
* the top, put it there.
* NOTE: When on_caption is TRUE
* then on_top must be also!
*/
if (state.on_caption)
MoveToTopWindowCap();
else
{
if (state.on_top)
if (GetWindow(prog.hWnd,GW_HWNDFIRST) != prog.hWnd)
ShowWindow(prog.hWnd, SW_SHOWNA);
}
/*
* Invalidate the client rectangle
* to paint the graph
*/
InvalidateRect(prog.hWnd, NULL, FALSE);
}
/*
* Reset the message counter and
* start a new timer.
*/
graph.msg_count = 0;
SetProgramTimer(state.update_time - 9);
} /* DoTimmer */
/************************************************************************
* This draws a 3D frame on the given rectangle 'rect' with a width of
* 'frame_width'. It returns a RECT that gives the coordinates for the
* face of the button like structure.
*
* INPUT: hdc = The device context.
* rect = The rectangle to put the frame in.
* frame_width = The width to make the frame.
*
* OUTPUT: temp_rect = A rectangle definition of the area inside the frame.
*/
RECT Draw3DFrame(HDC hDC, RECT Rect, int frame_width)
{
POINT frame[5]; // Points for the frame
int in_value; // Half the length of the smallest side
int oldDC; // Holds original DC
RECT tmpRect; // Stores the area inside the frame
HRGN tmpRgn; // Holds newly created region
oldDC = SaveDC(hDC);
/*
* Get a value that is half the
* length of the smallest side.
*/
if (Rect.right-Rect.left < Rect.bottom-Rect.top)
in_value = (Rect.right - Rect.left) / 2;
else
in_value = (Rect.bottom - Rect.top) / 2;
/*
* Build the polygon that will
* make the dark shaded sides
* of the 3d frame.
*/
frame[0].x = Rect.right;
frame[0].y = Rect.top;
frame[1].x = Rect.right;
frame[1].y = Rect.bottom;
frame[2].x = Rect.left;
frame[2].y = Rect.bottom;
frame[3].x = Rect.left+in_value;
frame[3].y = Rect.bottom-in_value;
frame[4].x = Rect.right-in_value;
frame[4].y = Rect.top+in_value;
/*
* Make sure the frame width
* is smaller then 'in_value'
*/
frame_width = (frame_width > in_value) ? in_value : frame_width;
/*
* This defines the face of
* the structure.
*/
tmpRect = Rect;
tmpRect.left += frame_width;
tmpRect.top += frame_width;
tmpRect.right -= frame_width;
tmpRect.bottom -= frame_width;
/*
* Draw the face of the
* button like structure.
*/
tmpRgn = CreateRectRgn(tmpRect.left, tmpRect.top,
tmpRect.right, tmpRect.bottom);
FillRgn(hDC, tmpRgn, GetStockObject(LTGRAY_BRUSH));
DeleteObject(tmpRgn);
/*
* Don't paint over the face
* of the structure that was
* just painted.
*/
ExcludeClipRect(hDC, tmpRect.left, tmpRect.top,
tmpRect.right, tmpRect.bottom);
/*
* Create and fill the rectangles
* of the high lighted and darkened
* areas of the button like structure.
*/
tmpRgn = CreateRectRgn(Rect.left, Rect.top, Rect.right, Rect.bottom);
FillRgn(hDC, tmpRgn, GetStockObject(WHITE_BRUSH));
DeleteObject(tmpRgn);
tmpRgn = CreatePolygonRgn(frame, 5, WINDING);
FillRgn(hDC, tmpRgn, GetStockObject(GRAY_BRUSH));
DeleteObject(tmpRgn);
RestoreDC(hDC,oldDC);
/*
* Return the face rectangle.
*/
return(tmpRect);
} /* Draw3DFrame */
/************************************************************************
* This function draws the graph of the system load. It does this by
* making a polygon out of its points.
*
* INPUT: hDC = The device context.
* Rect = The rectangle to put the frame in.
*
* OUTPUT: NONE
*/
void PlotGraph(HDC hDC, RECT Rect)
{
HANDLE tmpObj1; // A prior object's handle
HANDLE tmpObj2; // A prior object's handle
int oldMap; // Holds the past map mode
int oldDC; // Holds original DC
oldDC = SaveDC(hDC);
/*
* Set mapping mode.
*/
oldMap = SetMapMode(hDC, MM_ANISOTROPIC);
/*
* Invert the graph or keep it
* normal depending on the user's
* choice.
*/
if (state.graph_type == IDSD_QUEUE)
{
SetWindowOrg(hDC, 0, 0);
SetWindowExt(hDC, MAX_POINTS - 1, graph.apex);
SetViewportOrg(hDC, Rect.left, Rect.top);
SetViewportExt(hDC, Rect.right-(2*Rect.left)+1,
Rect.bottom-(2*Rect.top)+1);
tmpObj1 = SelectObject(hDC, GetStockObject(BLACK_PEN));
tmpObj2 = SelectObject(hDC, CreateSolidBrush(RGB_YELLOW));
}
else
{
SetWindowOrg(hDC, 0, 0);
SetWindowExt(hDC, MAX_POINTS - 1, -graph.apex);
SetViewportOrg(hDC, Rect.left, Rect.bottom-1);
SetViewportExt(hDC, Rect.right-(2*Rect.left)+1,
Rect.bottom-(2*Rect.top)+1);
tmpObj1 = SelectObject(hDC, GetStockObject(BLACK_PEN));
tmpObj2 = SelectObject(hDC, CreateSolidBrush(RGB_BLUE));
graph.table[LAST_POINT+1].y = 0;
graph.table[LAST_POINT+2].y = 0;
}
/*
* Draw the polygon.
*/
Polygon(hDC, graph.table, MAX_POINTS_ALL);
DeleteObject(SelectObject(hDC, tmpObj2));
DeleteObject(SelectObject(hDC, tmpObj1));
/*
* Adjust the last points
* back to where they were.
*/
graph.table[LAST_POINT+1].y = graph.apex;
graph.table[LAST_POINT+2].y = graph.apex;
/*
* Reset the the map mode.
*/
SetMapMode(hDC, oldMap);
RestoreDC(hDC, oldDC);
} /* PlotGraph */
/************************************************************************
* This function paints the system graph and its frame.
*
* INPUT: hwnd = This window's handle.
*
* OUTPUT: NONE
*
*/
void PaintGraph(HWND hwnd)
{
PAINTSTRUCT ps; // Paint structure of this function
RECT Rect; // The client rectangular coordinates
HDC hDC; // Handle to a display context
HBITMAP buf_bitmap; // Holds a bitmaped image of the output
HDC buf_hDC; // A memory device context equal to hdc
RECT inside_rect;// A rectangular area of the inside frame
/*
* Start painting session and
* get the client's rectangular
* coordinates.
*/
hDC = BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&Rect);
/*
* Create a memory DC the same
* size as the updated rectangle
* and copy it's image into it.
*/
buf_hDC = CreateCompatibleDC(hDC);
buf_bitmap = CreateCompatibleBitmap(hDC, Rect.right-Rect.left,
Rect.bottom-Rect.top);
SelectObject(buf_hDC, buf_bitmap);
/*
* Draw the frame around the graph.
*
*/
inside_rect = Draw3DFrame(buf_hDC, Rect, DEF_FRAME_WIDTH);
/*
* Now draw the graph inside the
* frame and copy that into the
* dummy bitmap!
*/
PlotGraph(buf_hDC, inside_rect);
/*
* Finally, copy the bitmap onto
* the rectangle.
*/
BitBlt(hDC, Rect.left, Rect.top, Rect.right-Rect.left,
Rect.bottom-Rect.top,
buf_hDC, 0, 0, SRCCOPY);
/*
* Delete the space taken up by
* the two temporary work areas.
*/
DeleteDC(buf_hDC);
DeleteObject(buf_bitmap);
EndPaint(hwnd, &ps);
} /* PaintGraph */
/************************************************************************
* This function enables a window to be sized smaller then normal. We do
* this by changing what Windows thinks is the smallest it can size a
* window.
*
* INPUT: lParam = is a long pointer to an array of 5 POINT
* data structures.
*
* OUTPUT: NONE
*
* NOTE: I tryed to make the size of the frame smaller but Windows didn't
* seem to like that. The sizes I picked seem to work fine. If you
* notice that when you size a window and the background of the
* desktop "blackens" then make the size larger.
*/
void SetMinSize(LONG lParam)
{
LPPOINT rgpt = (LPPOINT) lParam;
/*
* Increment to the point
* that contains the min
* values.
*/
rgpt++; rgpt++; rgpt++;
rgpt->x = 3 * GetSystemMetrics(SM_CXSIZE); // These values
rgpt->y = GetSystemMetrics(SM_CYSIZE); // work fine.
} /* SetMinSize */
/************************************************************************
* This function is called by Windows when it sends me a message.
*
* INPUT: hWnd = The window handle.
* message = The message to look at.
* wParam = The parameter of the message.
* lParam = The parameter of the message.
*
* OUTPUT: NONE
*
*************************************************************************/
long FAR PASCAL MainProc (HWND hWnd, unsigned message,
WORD wParam, LONG lParam)
{
switch(message)
{
case WM_TIMER: // Timer to get graph point or menu.
DoTimmer(wParam);
break;
case WM_GETMINMAXINFO: // Makes the window size smaller.
SetMinSize(lParam);
return(DefWindowProc(hWnd, message, wParam, lParam));
case WM_PAINT: // Paints the graph
PaintGraph(hWnd);
break;
case WM_QUERYOPEN: // Keeps track of when were maximized
state.iconic = FALSE;
return(DefWindowProc(hWnd, message, wParam, lParam));
case WM_SIZE: // Keeps track of when were minimized
if (wParam == SIZEICONIC)
state.iconic = TRUE;
return(DefWindowProc(hWnd, message, wParam, lParam));
case WM_NCCALCSIZE: // Keeps track of the window size
if ((! state.on_caption) && (! IsIconic(hWnd)))
CopyRect(&state.window_position, (LPRECT) lParam);
return(DefWindowProc(hWnd, message, wParam, lParam));
case WM_MOVE: // Kills the menu if the user moves the icon
if (IsIconic(hWnd))
KillTimer(hWnd, 2);
return(DefWindowProc(hWnd, message, wParam, lParam));
case WM_QUERYDRAGICON: // Changes the cursor when dragging the icon
return(LoadCursor(prog.hInstance, "ICON_CURSOR"));
case WM_RBUTTONDOWN: // Changes the window style to size it
ChangeWinStyle();
break;
case WM_NCLBUTTONDOWN: // Starts the menu timer
if (IsIconic(hWnd))
SetTimer(hWnd, 2, GetDoubleClickTime(), NULL);
return(DefWindowProc(hWnd, message, wParam, lParam));
case WM_NCLBUTTONDBLCLK:// Stops the menu from showing
KillTimer(hWnd, 2);
return(DefWindowProc(hWnd, message, wParam, lParam));
case WM_SETCURSOR: // Kills the dialog box
if (prog.halt)
{
if ( (LOWORD(lParam) == (unsigned)HTERROR) &&
(HIWORD(lParam) == WM_LBUTTONDOWN) )
EndDialog(GetActiveWindow(), TRUE);
}
return(DefWindowProc(hWnd, message, wParam, lParam));
case WM_LBUTTONDOWN: // Allows moving of a whole window
if (! IsIconic(hWnd))
{
if (! popup_mode)
{
SetCursor(LoadCursor(NULL, IDC_SIZE));
return(DefWindowProc(hWnd, WM_NCLBUTTONDOWN,
HTCAPTION, lParam));
}
else
DialogBox(prog.hInstance, (LPSTR) "MENU_BOX",
hWnd, MakeProcInstance(
(FARPROC) MenuDialog, prog.hInstance));
}
return(DefWindowProc(hWnd, message, wParam, lParam));
case WM_DESTROY: // Kills all timers and leaves.
KillTimer(hWnd, 1);
KillTimer(hWnd, 2);
PostQuitMessage(TRUE);
break;
default:
return(DefWindowProc(hWnd, message, wParam, lParam));
}
return((long) 0);
} /* end MainProc */
/************************************************************************
* This function positions the menu dialog box where the mouse cursor is
* and if the program is iconic then positions it on the icon.
*
* INPUT: NONE
*
* OUTPUT: NONE
*/
void SetDlgPos(HWND hDlg)
{
POINT Point;
RECT rect;
int iX, iY;
RECT windRect;
GetWindowRect(hDlg, &rect);
if (state.iconic)
{
GetWindowRect(prog.hWnd, &windRect);
Point.x = windRect.left;
Point.y = windRect.top;
iX = Point.x + (rect.right - rect.left);
iY = Point.y + (rect.bottom - rect.top);
}
else
{
GetCursorPos(&Point);
iX = Point.x + (rect.right - rect.left);
iY = Point.y + (rect.bottom - rect.top);
}
if ((iX > GetSystemMetrics(SM_CXSCREEN)) ||
(iY > GetSystemMetrics(SM_CYSCREEN)) )
{
if ((iX > GetSystemMetrics(SM_CXSCREEN)) &&
(iY > GetSystemMetrics(SM_CYSCREEN)) )
SetWindowPos(hDlg, 1, Point.x + 3 - (rect.right-rect.left),
Point.y + 3 - (rect.bottom-rect.top),
0, 0, SWP_NOSIZE);
else
{
if (iY > GetSystemMetrics(SM_CYSCREEN))
SetWindowPos(hDlg, 1, Point.x - 3,
Point.y + 3 - (rect.bottom-rect.top),
0, 0, SWP_NOSIZE);
if (iX > GetSystemMetrics(SM_CXSCREEN))
SetWindowPos(hDlg, 1, Point.x + 3 - (rect.right-rect.left),
Point.y - 3,
0, 0, SWP_NOSIZE);
}
}
else
SetWindowPos(hDlg, 1, Point.x-3, Point.y-3, 0, 0, SWP_NOSIZE);
} /* SetDlgPos */
/************************************************************************
* This handles all the messages for the configuration dialog box.
*
* INPUT: hDlg = The dialog handle.
* imessage = The message to look at.
* wParam = The parameter of the message.
* lParam = The parameter of the message.
*
* OUTPUT: NONE
*/
#pragma argsused
BOOL FAR PASCAL SetupDialog( HWND hDlg, unsigned imessage,
WORD wParam, LONG lParam)
{
static short update_rate;
static short graph_type;
static BOOL auto_rescale;
static BOOL keep_on_top;
static BOOL follow_window;
switch (imessage)
{
case WM_INITDIALOG:
prog.halt = TRUE;
follow_window = state.on_caption;
keep_on_top = state.on_top;
update_rate = state.update_time;
graph_type = state.graph_type;
auto_rescale = state.auto_rescale;
/*
* Check the buttons to the
* current setup.
*/
CheckRadioButton(hDlg, IDSD_1SEC, IDSD_5SEC, update_rate);
CheckRadioButton(hDlg, IDSD_QUEUE, IDSD_INV_QUEUE, graph_type);
CheckDlgButton(hDlg, IDSD_AUTO_RESCALE, auto_rescale);
CheckDlgButton(hDlg, IDSD_ON_TOP, keep_on_top);
CheckDlgButton(hDlg, IDSD_ON_CAPTION, follow_window);
return(FALSE);
case WM_DESTROY:
prog.halt = FALSE;
break;
case WM_ACTIVATEAPP:
EndDialog(hDlg, TRUE);
return(FALSE);
case WM_COMMAND:
switch (wParam)
{
case IDOK:
if (state.graph_type != graph_type)
state.graph_type = graph_type;
if (state.update_time != update_rate)
{
state.update_time = update_rate;
SetProgramTimer(state.update_time - 9);
}
if (state.auto_rescale != auto_rescale)
state.auto_rescale = ! state.auto_rescale;
if (state.on_top != keep_on_top)
state.on_top = ! state.on_top;
if (state.on_caption != follow_window)
{
state.on_caption = ! state.on_caption;
/*
* If on_caption is shut off put us
* back to normal.
*/
if (! state.on_caption)
SetWindowPos(prog.hWnd, 1,
state.window_position.left,
state.window_position.top,
(state.window_position.right -
state.window_position.left),
(state.window_position.bottom -
state.window_position.top),
SWP_NOZORDER);
}
/*
* Save the setup.
*/
if (lParam == TRUE)
SetProgramSetup();
EndDialog(hDlg, TRUE);
break;
case IDCANCEL:
EndDialog(hDlg, TRUE);
break;
case IDSD_ON_CAPTION:
follow_window = ! follow_window;
CheckDlgButton(hDlg, IDSD_ON_CAPTION, follow_window);
keep_on_top = TRUE;
CheckDlgButton(hDlg, IDSD_ON_TOP, keep_on_top);
break;
case IDSD_ON_TOP:
keep_on_top = ! keep_on_top;
CheckDlgButton(hDlg, IDSD_ON_TOP, keep_on_top);
follow_window = FALSE;
CheckDlgButton(hDlg, IDSD_ON_CAPTION, follow_window);
break;
case IDSD_AUTO_RESCALE:
auto_rescale = ! auto_rescale;
CheckDlgButton(hDlg, IDSD_AUTO_RESCALE, auto_rescale);
break;
case IDSD_1SEC:
case IDSD_2SEC:
case IDSD_5SEC:
update_rate = wParam;
CheckRadioButton(hDlg, IDSD_1SEC, IDSD_5SEC, wParam);
break;
case IDSD_INV_QUEUE:
case IDSD_QUEUE:
graph_type = wParam;
CheckRadioButton(hDlg, IDSD_QUEUE, IDSD_INV_QUEUE, wParam);
break;
case IDSD_SAVE_SETUP:
SendMessage(hDlg, WM_COMMAND, IDOK, TRUE);
break;
default:
return(FALSE);
}
break;
default:
return(FALSE);
}
return(TRUE);
} /* config_dialog */
/************************************************************************
* This handles all the messages for the ware dialog box.
*
* INPUT: hDlg = The dialog handle.
* imessage = The message to look at.
* wParam = The parameter of the message.
* lParam = The parameter of the message.
*
* OUTPUT: NONE
*/
#pragma argsused
BOOL FAR PASCAL WareDialog(HWND hDlg, unsigned imessage,
WORD wParam, LONG lParam)
{
switch (imessage)
{
case WM_INITDIALOG:
break;
case WM_ACTIVATEAPP:
EndDialog(hDlg, TRUE);
return(FALSE);
case WM_COMMAND:
EndDialog(hDlg, TRUE);
break;
default:
return(FALSE);
}
return(TRUE);
} /* WareDialog */
/************************************************************************
* This handles all the messages for the about dialog box.
*
* INPUT: hDlg = The dialog handle.
* imessage = The message to look at.
* wParam = The parameter of the message.
* lParam = The parameter of the message.
*
* OUTPUT: NONE
*/
#pragma argsused
BOOL FAR PASCAL AboutDialog(HWND hDlg, unsigned imessage,
WORD wParam, LONG lParam)
{
switch (imessage)
{
case WM_INITDIALOG:
prog.halt = TRUE;
SetDlgItemText(hDlg, IDAD_VERSION, (LPSTR) IDAD_VERSION_STR);
SetDlgItemText(hDlg, IDAD_AUTHOR, (LPSTR) IDAD_AUTHOR_STR);
break;
case WM_ACTIVATEAPP:
EndDialog(hDlg, TRUE);
return(FALSE);
case WM_DESTROY:
prog.halt = FALSE;
break;
case WM_COMMAND:
switch (wParam)
{
case IDOK:
EndDialog(hDlg, TRUE);
break;
case IDAD_WARE:
DialogBox(prog.hInstance, (LPSTR) "WARE_BOX", hDlg,
MakeProcInstance((FARPROC) WareDialog, prog.hInstance));
break;
default:
return(FALSE);
}
break;
default:
return(FALSE);
}
return(TRUE);
} /* AboutDialog */
/************************************************************************
* This handles all the messages for the menu dialog box. If the user
* clicks on another application we end this dialog.
*
* INPUT: hDlg = The dialog handle.
* imessage = The message to look at.
* wParam = The parameter of the message.
* lParam = The parameter of the message.
*
* OUTPUT: NONE
*/
#pragma argsused
BOOL FAR PASCAL MenuDialog(HWND hDlg, unsigned imessage,
WORD wParam, LONG lParam)
{
switch (imessage)
{
case WM_INITDIALOG:
SetDlgPos(hDlg);
if (IsIconic(prog.hWnd))
SetDlgItemText(hDlg, IDMD_MINIMIZE, (LPSTR) "Maximize");
prog.halt = TRUE;
break;
case WM_DESTROY:
prog.halt = FALSE;
break;
case WM_ACTIVATEAPP:
EndDialog(hDlg, TRUE);
return(FALSE);
case WM_COMMAND:
switch (wParam)
{
case IDCANCEL:
EndDialog(hDlg, TRUE);
break;
case IDMD_MINIMIZE:
EndDialog(hDlg, TRUE);
if (IsIconic(prog.hWnd))
{
ShowWindow(prog.hWnd, SW_RESTORE);
SetDlgItemText(hDlg, IDMD_MINIMIZE, (LPSTR) "Maximize");
}
else
{
ShowWindow(prog.hWnd, SW_MINIMIZE);
SetDlgItemText(hDlg, IDMD_MINIMIZE, (LPSTR) "Minimize");
}
break;
case IDMD_SETUP:
EndDialog(hDlg, TRUE);
DialogBox(prog.hInstance,
(LPSTR) "SETUP_BOX",
prog.hWnd,
MakeProcInstance((FARPROC) SetupDialog,
prog.hInstance));
break;
case IDMD_ABOUT:
EndDialog(hDlg, TRUE);
DialogBox(prog.hInstance,
(LPSTR) "ABOUT_BOX",
prog.hWnd,
MakeProcInstance((FARPROC) AboutDialog, prog.hInstance));
break;
case IDMD_RESCALE:
EndDialog(hDlg, TRUE);
RescaleGraph();
break;
case IDMD_CLOSE:
EndDialog(hDlg, TRUE);
PostMessage(prog.hWnd, WM_CLOSE, 0, 0);
break;
default:
return(FALSE);
}
break;
default:
return(FALSE);
}
return(TRUE);
} /* MenuDialog */